package cn.controller;

import cn.entity.AccessToken;
import cn.entity.WechatAccountConfig;
import cn.hutool.http.HttpUtil;
import cn.message.TextMessage;
import cn.pojo.SubScribedUser;
import cn.pojo.SysClientUser;
import cn.pojo.Utils;
import cn.service.ISysClientUserService;
import cn.service.TemplateMessageService;
import cn.util.Wechat;
import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Controller
@RequestMapping
@Slf4j
public class WxController {

    private static final String AUTHORIZE_SNSAPI = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=RETURN_URL&response_type=code&scope=snsapi_base&state=123#wechat_redirect";

    private static final String ADAW = " https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

    private static final String ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    private static final String USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    @Autowired
    WechatAccountConfig wechatAccountConfig;

    @Autowired
    private ISysClientUserService sysClientUserService;


    @GetMapping("/redirectUrl")
    public String redirectUrl(){
        String urls = AUTHORIZE_SNSAPI.replace("APPID", wechatAccountConfig.mpAppId).replace("RETURN_URL", "http://ypdquk.natappfree.cc/getWechatReturn");
        return "redirect:"+urls;
    }

    @GetMapping("/getWechatReturn")
    public String getWechatReturn(Model model, HttpServletRequest request) {
        String code = request.getParameter("code");
        String accessToken = ACCESS_TOKEN.replace("APPID", wechatAccountConfig.mpAppId).
                replace("SECRET", wechatAccountConfig.mpAppSecret).
                replace("CODE", code);
        String s = HttpUtil.get(accessToken);
        String access_token = JSONObject.parseObject(s).getString("access_token");
        String openId = JSONObject.parseObject(s).getString("openid");
        String userInfo = USER_INFO.replace("ACCESS_TOKEN",access_token).replace("OPENID",openId);
        String user = HttpUtil.get(userInfo);
        SubScribedUser subScribedUser = JSONObject.parseObject(user, SubScribedUser.class);
        System.out.println("用户信息：");
        System.out.println(subScribedUser);
        model.addAttribute("user",subScribedUser);
        return "index";
    }

    @GetMapping("/getIndex")
    public String getIndex(Model model) {
        Map<String, Object> map = new HashMap<>();
        SubScribedUser subScribedUser = new SubScribedUser();
        subScribedUser.setNickname("hahhhhh");
        subScribedUser.setSex(0L);
        subScribedUser.setHeadimgurl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTINFI6rF4T82cpyia8icJLeM4dpG6NEmdJ8zFSVsEDWXjk9qUpmou7aHmr706X3EcQkfNMmfeVmAIIg/132");
        map.put("mpAppId", wechatAccountConfig.mpAppId);
        map.put("mpAppSecret", wechatAccountConfig.mpAppSecret);
        map.put("user", subScribedUser);
        model.addAllAttributes(map);
        return "index";
    }

    @GetMapping("/getSysClientUserAll")
    @ResponseBody
    public Utils<SysClientUser> getSysClientUserAll(){
        List<SysClientUser> all = sysClientUserService.getAll();
        Utils<SysClientUser> userUtils = new Utils<>();
        userUtils.setCode(0);
        userUtils.setCount(1000);
        userUtils.setData(all);
        System.out.println(userUtils);
        return userUtils;
    }

    @GetMapping("/getTable")
    public String getTable(){
        return "table";
    }

    @GetMapping("/")
    @ResponseBody
    public String check(@RequestParam String signature,
                        @RequestParam String timestamp,
                        @RequestParam String nonce,
                        @RequestParam String echostr){
        System.out.println("signature:"+signature);
        String token = "baiyajie";
        List<String> list = Arrays.asList(token,timestamp,nonce);
        Collections.sort(list);
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : list) {
            stringBuilder.append(s);
        }
        //加密
        try {
            MessageDigest sha1 = MessageDigest.getInstance("sha1");
            byte[] digest = sha1.digest(stringBuilder.toString().getBytes());
            StringBuilder sum = new StringBuilder();
            for (byte b : digest) {
                sum.append(Integer.toHexString((b>>4)&15));
                sum.append(Integer.toHexString(b&15));
            }
            System.out.println("sum:"+sum);
            if (!StringUtils.isEmpty(signature)&&signature.equals(sum.toString())){
                return echostr;
            }
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @PostMapping("/")
    @ResponseBody
    public String receiveMessage(HttpServletRequest request) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        Map<String,String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(inputStream);
            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for (Element element : elements) {
                map.put(element.getName(),element.getStringValue());
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
        System.out.println(map);
        //回复消息
        String event = map.get("MsgType");
        String message = "";
        switch (event){
            case "text":
                message = getReplyMesage(map,"");
                break;
            case "event":
                message = handleEvent(map);
                break;
            default:
                break;
        }
        return message;
    }

    /**
     * 获得回复的消息内容
     * @param map
     * @return
     */
    private String getReplyMesage(Map<String,String> map,String message){
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setCreateTime(System.currentTimeMillis()/1000);
        textMessage.setMsgType("text");
        if (message !=""){
            textMessage.setContent(message);
        }else {
            textMessage.setContent("开发中！");
        }

        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        return xStream.toXML(textMessage);
    }

    private String handleEvent(Map<String,String> map){
        String event = map.get("Event");
        AccessToken accessToken = Wechat.getToken(wechatAccountConfig.mpAppId, wechatAccountConfig.mpAppSecret);
        switch (event){
            case "CLICK":
                String openId = map.get("FromUserName");
                TemplateMessageService.sendTemp(accessToken.getAccess_token(),openId);
                return "";
            case "subscribe":
                return getReplyMesage(map,"欢迎订阅测试公众号！");
            default:
                return getReplyMesage(map,"");
        }
    }
}
